package com.bamboo.toolbox.exporter.dialog;

import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.DialogWrapper;
import com.bamboo.toolbox.core.intellij.thread.BackgroundTaskUtils;
import com.bamboo.toolbox.core.swing.TextScrollPane;
import com.bamboo.toolbox.core.utils.JsonUtils;
import com.bamboo.toolbox.exporter.DatasourceTableGenerator;
import com.bamboo.toolbox.exporter.model.Database;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.event.ItemEvent;
import java.util.Arrays;
import java.util.stream.Collectors;


/**
 * @author luzhiqing
 * @version 1.0
 * @date 2022/10/21
 */
public class ExportTableDialog extends DialogWrapper {
    private final JPanel centerPanel;
    private final JComboBox<String> databaseNames;
    private final java.util.List<Database> databases;
    private final TextScrollPane targetDatabase;
    private final JTextArea outputPath;
    private final JTextArea tableNames;
    private final SpringLayout layout;
    private final Project project;


    public ExportTableDialog(@Nullable Project project, java.util.List<Database> databases, String outputPathStr) {
        super(project);
        this.project = project;
        this.layout = new SpringLayout();
        this.centerPanel = new JPanel(this.layout);
        this.databases = databases;
        this.databaseNames = new ComboBox<>(databases.stream().map(Database::getName).toArray(String[]::new));
        this.tableNames = new JTextArea();
        this.targetDatabase = new TextScrollPane();
        this.outputPath = new JTextArea(outputPathStr);
    }

    @Override
    public void init() {
        super.init();
        tableNames.setLineWrap(true);
        outputPath.setLineWrap(true);
        centerPanel.add(databaseNames);
        centerPanel.add(tableNames);
        centerPanel.add(targetDatabase);
        centerPanel.add(outputPath);
        this.constraintsLayout();
        databaseNames.addItemListener(e -> {
            if (ItemEvent.SELECTED == e.getStateChange()) {
                int selectedIndex = databaseNames.getSelectedIndex();
                Database database = databases.get(selectedIndex);
                targetDatabase.setText(database.toJson());
            }
        });
    }

    protected void constraintsLayout() {

        // 约束
        // databaseBoxCons
        SpringLayout.Constraints databaseBoxCons = layout.getConstraints(databaseNames);
        databaseBoxCons.setX(Spring.constant(5));
        databaseBoxCons.setY(Spring.constant(5));
        databaseBoxCons.setWidth(Spring.constant(160));
        databaseBoxCons.setHeight(Spring.constant(30));

        SpringLayout.Constraints databaseCons = layout.getConstraints(targetDatabase);
        databaseCons.setX(Spring.constant(5));
        databaseCons.setY(databaseBoxCons.getConstraint(SpringLayout.SOUTH));
        databaseCons.setConstraint(SpringLayout.EAST, databaseBoxCons.getConstraint(SpringLayout.EAST));


        SpringLayout.Constraints tablesCons = layout.getConstraints(tableNames);
        tablesCons.setX(Spring.sum(databaseBoxCons.getConstraint(SpringLayout.EAST), Spring.constant(5)));
        tablesCons.setY(Spring.constant(5));


        SpringLayout.Constraints outputPathCons = layout.getConstraints(outputPath);
        outputPathCons.setX(Spring.constant(5));
        outputPathCons.setY(databaseCons.getConstraint(SpringLayout.SOUTH));
        Spring max = Spring.max(databaseCons.getConstraint(SpringLayout.SOUTH), tablesCons.getConstraint(SpringLayout.SOUTH));
        outputPathCons.setConstraint(SpringLayout.NORTH, Spring.sum(max, Spring.constant(5)));
        outputPathCons.setHeight(Spring.constant(50));

        /*
         * 内容面板（容器）的约束设置，即确定 组件 和 容器的右边和底边 之间的间隙大小
         */
        // 获取容器的约束对象
        SpringLayout.Constraints panelCons = layout.getConstraints(centerPanel);

        // 设置容器的 东边坐标 为 文本框的东边坐标 + 5
        Spring maxWiSpring = Spring.max(outputPathCons.getConstraint(SpringLayout.EAST), tablesCons.getConstraint(SpringLayout.EAST));
        panelCons.setConstraint(SpringLayout.EAST, Spring.sum(maxWiSpring, Spring.constant(5)));

        // 计算出 按钮 和 文本框 的 南边坐标 的 值较大者
        Spring maxHeightSpring = outputPathCons.getConstraint(SpringLayout.SOUTH);


        // 设置容器的 南边坐标 为 maxHeightSpring + 5
        panelCons.setConstraint(SpringLayout.SOUTH, Spring.sum(maxHeightSpring, Spring.constant(5)));

    }

    @Override
    protected @Nullable JComponent createCenterPanel() {
        return centerPanel;
    }

    @Override
    protected void doOKAction() {
        try {
            this.doOk();
        } finally {
            super.doOKAction();
        }
    }

    private void doOk() {
        BackgroundTaskUtils.execute(new Task.Backgroundable(project, "表结构导出") {
            @Override
            public void run(@NotNull ProgressIndicator indicator) {
                // Set the progress bar percentage and text
                indicator.setFraction(0.10);
                indicator.setText("导出表结构开始");
                try {
                    Class.forName("oracle.jdbc.OracleDriver");
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    return;
                }
                String databaseJson = targetDatabase.getText();
                Database target = JsonUtils.toObject(databaseJson, Database.class);

                String[] tables = tableNames.getText().split(",");
                String outputPathStr = outputPath.getText();

                if (0 == tables.length) {
                    throw new RuntimeException("表名不能为空！");
                }
                if (null == target) {
                    throw new RuntimeException("未选择目标数据库！");
                }
                DatasourceTableGenerator.buildDatabaseProperties(
                        target.getUrl(),
                        target.getUserName(),
                        target.getPassword()
                );
                DatasourceTableGenerator.setIndicator(indicator);
                DatasourceTableGenerator.setTables(Arrays.stream(tables).collect(Collectors.toList()));
                DatasourceTableGenerator.setOutputPath(outputPathStr);
                DatasourceTableGenerator.setOutputFileName("表结构");
                DatasourceTableGenerator.gen();
                indicator.setFraction(1);
                indicator.setText("导出表结构完成");
                DatasourceTableGenerator.clean();
            }
        });
    }
}
